# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
  
  def put_form_for(object, template, &proc)
    name = object.class.name.singularize.underscore # hacky!
    form_for object, :html => { :onsubmit => uri_template_onsubmit(template, "#{name}[%s]"), :method => "put" }, &proc
  end
  
  def uri_template_onsubmit(template, form_template=nil)
    ApplicationHelper::UriTemplate.new(template).to_onsubmit(form_template)
  end
  
  class UriTemplate
    
    attr_reader :template
    
    def initialize(template)
      @template = template
      @keys, @parts = parse(template)
    end
    
    def to_js_function
      %|function(#{@keys * ","}) { return #{@parts.join("+")} }|
    end
    
    def to_form_function(form_template=nil)
      form_template ||= "%s"
      form_readers = @keys.collect do |p| 
        name = form_template % p.to_s
        "form[#{name.inspect}].value" # TODO: use prototype to get field value
      end
      <<-JS
        function(form) {
          var f = #{to_js_function};
          return f(#{form_readers * ","});
        }
      JS
    end
    
    def to_onsubmit(form_template=nil)
      f = to_form_function(form_template).split("\n").collect(&:strip).join
      "var f = #{f}; this.action = f(this); return true;"
    end
    
  protected
  
    def parse(template)
      keys, parts = [], []
      builder = ActionController::Routing::RouteBuilder.new
      builder.segments_for_route_path(template).collect do |s|
        if s.is_a?(ActionController::Routing::DynamicSegment)
          keys << s.key
          parts << s.key
        else
          parts << s.to_s.inspect
        end
      end
      [keys, parts]
    end
  end

  
end
